package com.koron.plan.web.repairplan.notified;

import org.apache.commons.collections4.CollectionUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.lang.reflect.Type;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author twcao
 * @title: RepairPlanNotifyHolder
 * @projectName GDH_EAM_V2
 * @description: 检修计划通知管理
 * @date 2021/9/1410:36
 */
@Component
public class RepairPlanNotifyHolder {

    /**
     * 待通知的对象
     */
    private List<RepairPlanNotify> notifies;

    @Autowired
    public RepairPlanNotifyHolder(List<RepairPlanNotify> notifies) {
        if(CollectionUtils.isEmpty(notifies)) {
            return;
        }
        this.notifies = notifies.stream().sorted(Comparator.comparingInt(RepairPlanNotify::getOrder)).collect(Collectors.toList());
    }

    /**
     * 初始化前
     * @param factory 会话
     * @param vo 实体
     * @return 是否成功
     */
    public boolean initializeBefore(SessionFactory factory, Object vo) {
        notifies.stream().filter(row -> genericConstraint(row, vo) && row.filter(factory, vo)).forEach(row -> row.initializeBefore(factory, vo));
        return true;
    }

    /**
     * 保存之前
     * @param factory 会话
     * @param vo 实体
     * @return 是否成功
     */
    public boolean saveBefore(SessionFactory factory, Object vo) {
        notifies.stream().filter(row -> genericConstraint(row, vo) && row.filter(factory, vo)).forEach(row -> row.saveBefore(factory, vo));
        return true;
    }

    /**
     * 保存之后
     * @param factory 会话
     * @param vo 实体
     * @return 是否成功
     */
    public boolean saveAfter(SessionFactory factory, Object vo) {
        notifies.stream().filter(row -> genericConstraint(row, vo) && row.filter(factory, vo)).forEach(row -> row.saveAfter(factory, vo));
        return true;
    }

    /**
     * 删除之前
     * @param factory 会话
     * @param vo 实体
     * @return
     */
    public boolean deleteBefore(SessionFactory factory, Object vo) {
        notifies.stream().filter(row -> genericConstraint(row, vo) && row.filter(factory, vo)).forEach(row -> row.deleteBefore(factory, vo));
        return true;
    }

    /**
     * 删除之后
     * @param factory 会话
     * @param vo 实体
     * @return
     */
    public boolean deleteAfter(SessionFactory factory, Object vo) {
        notifies.stream().filter(row -> genericConstraint(row, vo) && row.filter(factory, vo)).forEach(row -> row.deleteAfter(factory, vo));
        return true;
    }

    /**
     * 泛型约束 RepairPlanNotify 是否有Object实际类型的约束, 没有就跳过
     * @return 满足约束
     */
    private boolean genericConstraint(RepairPlanNotify notify, Object obj) {
        Type[] genericInterfaces = notify.getClass().getGenericInterfaces();
        for(Type type : genericInterfaces) {
            if(type instanceof ParameterizedTypeImpl) {
                ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) type;
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                for(Type t : actualTypeArguments) {
                    if(((Class) t).isAssignableFrom(obj.getClass())) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
